/*
 * socket.h
 *
 *  Created on: 2008-7-18
 *      Author: fanliangliang
 */

#ifndef SOCKET_H_
#define SOCKET_H_

#include "socket_address.h"

BEGIN_NAMESPACE_TOXIC

class Socket {
	CLASS_UNCOPYABLE(Socket)
public:
	enum SocketType {
		TCP_SOCKET,
		UDP_SOCKET,
	};

	enum SocketState {
		UNCONNECTED_STATE,
		HOST_LOOKUP_STATE,
		CONNECTING_STATE,
		CONNECTED_STATE,
		CLOSING_STATE
	};

public:
	Socket(SocketType type);
	Socket(int descriptor, SocketType type, SocketState state);
	virtual ~Socket();

	void close();
	void connect(const IpAddress& address, uint16_t port);
	void connect(const SocketAddress& address);

	size_t send(const void* buffer, size_t length);
	size_t sendN(const void* buffer, size_t length);
	size_t receive(void* buffer, size_t length);
	size_t receiveN(void* buffer, size_t length);

	SocketAddress localAddress() const;
	IpAddress localIpAddress() const;
	uint16_t localPort() const;

	SocketAddress peerAddress() const;
	IpAddress peerIpAddress() const;
	uint16_t peerPort() const;

	int descriptor() const;
	SocketType type() const;
	SocketState state() const;
	bool isConnected() const;

private:
	void setState(SocketState state);

#if defined(PLATFORM_WIN32)
private:
	static SocketInitializer __the_fucking_winsock_initializer;
#endif

private:
	int _descriptor;
	SocketType _type;
	SocketState _state;
};

END_NAMESPACE_TOXIC

#endif /* SOCKET_H_ */
